package org.example.ding.controller;

import jakarta.validation.Valid;
import org.example.ding.dto.DishDto;
import org.example.ding.dto.DishCategoryDto;
import org.example.ding.entity.Dish;
import org.example.ding.entity.DishCategory;
import org.example.ding.service.DishService;
import org.example.ding.service.DishCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜品管理控制器
 */
@Controller
@RequestMapping("/admin/dishes")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private DishCategoryService dishCategoryService;

    /**
     * 菜品列表页面
     */
    @GetMapping
    public String listDishes(@RequestParam(defaultValue = "0") int page,
                            @RequestParam(defaultValue = "10") int size,
                            @RequestParam(required = false) Long categoryId,
                            @RequestParam(required = false) String keyword,
                            Model model) {
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        Page<Dish> dishPage;
        
        if (categoryId != null) {
            dishPage = dishService.getDishesByCategory(categoryId, pageable);
        } else if (keyword != null && !keyword.trim().isEmpty()) {
            dishPage = dishService.searchDishes(null, keyword, null, null, null, null, pageable);
        } else {
            dishPage = dishService.getDishes(pageable);
        }
        
        List<DishCategoryDto> categories = dishCategoryService.getAllCategoryDtos();
        
        model.addAttribute("dishPage", dishPage);
        model.addAttribute("categories", categories);
        model.addAttribute("currentCategoryId", categoryId);
        model.addAttribute("currentKeyword", keyword);
        
        return "admin/dishes/list";
    }

    /**
     * 显示创建菜品页面
     */
    @GetMapping("/create")
    public String showCreateForm(Model model) {
        model.addAttribute("dishDto", new DishDto());
        model.addAttribute("categories", dishCategoryService.getAllCategoryDtos());
        model.addAttribute("spiceLevels", Dish.SpiceLevel.values());
        model.addAttribute("cookingMethods", Dish.CookingMethod.values());
        return "admin/dishes/create";
    }

    /**
     * 处理创建菜品
     */
    @PostMapping("/create")
    public String createDish(@Valid @ModelAttribute("dishDto") DishDto dishDto,
                            BindingResult result,
                            Model model,
                            RedirectAttributes redirectAttributes) {
        
        if (result.hasErrors()) {
            model.addAttribute("categories", dishCategoryService.getAllCategoryDtos());
            model.addAttribute("spiceLevels", Dish.SpiceLevel.values());
            model.addAttribute("cookingMethods", Dish.CookingMethod.values());
            return "admin/dishes/create";
        }

        try {
            Dish dish = dishService.createDish(dishDto);
            redirectAttributes.addFlashAttribute("successMessage", 
                "菜品 \"" + dish.getName() + "\" 创建成功！");
            return "redirect:/admin/dishes";
        } catch (RuntimeException e) {
            result.rejectValue("name", "error.dishDto", e.getMessage());
            model.addAttribute("categories", dishCategoryService.getAllCategoryDtos());
            model.addAttribute("spiceLevels", Dish.SpiceLevel.values());
            model.addAttribute("cookingMethods", Dish.CookingMethod.values());
            return "admin/dishes/create";
        }
    }

    /**
     * 显示编辑菜品页面
     */
    @GetMapping("/{id}/edit")
    public String showEditForm(@PathVariable Long id, Model model) {
        Dish dish = dishService.findById(id)
            .orElseThrow(() -> new RuntimeException("菜品不存在"));
        
        DishDto dishDto = DishDto.fromDish(dish);
        
        model.addAttribute("dishDto", dishDto);
        model.addAttribute("categories", dishCategoryService.getAllCategoryDtos());
        model.addAttribute("spiceLevels", Dish.SpiceLevel.values());
        model.addAttribute("cookingMethods", Dish.CookingMethod.values());
        
        return "admin/dishes/edit";
    }

    /**
     * 处理编辑菜品
     */
    @PostMapping("/{id}/edit")
    public String editDish(@PathVariable Long id,
                          @Valid @ModelAttribute("dishDto") DishDto dishDto,
                          BindingResult result,
                          Model model,
                          RedirectAttributes redirectAttributes) {
        
        if (result.hasErrors()) {
            model.addAttribute("categories", dishCategoryService.getAllCategoryDtos());
            model.addAttribute("spiceLevels", Dish.SpiceLevel.values());
            model.addAttribute("cookingMethods", Dish.CookingMethod.values());
            return "admin/dishes/edit";
        }

        try {
            Dish dish = dishService.updateDish(id, dishDto);
            redirectAttributes.addFlashAttribute("successMessage", 
                "菜品 \"" + dish.getName() + "\" 更新成功！");
            return "redirect:/admin/dishes";
        } catch (RuntimeException e) {
            result.rejectValue("name", "error.dishDto", e.getMessage());
            model.addAttribute("categories", dishCategoryService.getAllCategoryDtos());
            model.addAttribute("spiceLevels", Dish.SpiceLevel.values());
            model.addAttribute("cookingMethods", Dish.CookingMethod.values());
            return "admin/dishes/edit";
        }
    }

    /**
     * 查看菜品详情
     */
    @GetMapping("/{id}")
    public String viewDish(@PathVariable Long id, Model model) {
        Dish dish = dishService.findById(id)
            .orElseThrow(() -> new RuntimeException("菜品不存在"));
        
        DishDto dishDto = DishDto.fromDish(dish);
        model.addAttribute("dishDto", dishDto);
        
        return "admin/dishes/view";
    }

    /**
     * 删除菜品
     */
    @PostMapping("/{id}/delete")
    public String deleteDish(@PathVariable Long id, RedirectAttributes redirectAttributes) {
        try {
            Dish dish = dishService.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
            
            dishService.deleteDish(id);
            redirectAttributes.addFlashAttribute("successMessage", 
                "菜品 \"" + dish.getName() + "\" 已删除！");
        } catch (RuntimeException e) {
            redirectAttributes.addFlashAttribute("errorMessage", e.getMessage());
        }
        
        return "redirect:/admin/dishes";
    }

    /**
     * 恢复菜品
     */
    @PostMapping("/{id}/restore")
    public String restoreDish(@PathVariable Long id, RedirectAttributes redirectAttributes) {
        try {
            Dish dish = dishService.findById(id)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));
            
            dishService.restoreDish(id);
            redirectAttributes.addFlashAttribute("successMessage", 
                "菜品 \"" + dish.getName() + "\" 已恢复！");
        } catch (RuntimeException e) {
            redirectAttributes.addFlashAttribute("errorMessage", e.getMessage());
        }
        
        return "redirect:/admin/dishes";
    }

    /**
     * 检查菜品名称是否可用 (AJAX)
     */
    @GetMapping("/api/check-name")
    @ResponseBody
    public ResponseEntity<Map<String, Boolean>> checkDishName(@RequestParam String name,
                                                             @RequestParam(required = false) Long excludeId) {
        boolean available;
        if (excludeId != null) {
            available = dishService.isDishNameAvailable(name, excludeId);
        } else {
            available = dishService.isDishNameAvailable(name);
        }
        
        Map<String, Boolean> response = new HashMap<>();
        response.put("available", available);
        return ResponseEntity.ok(response);
    }

    /**
     * 获取菜品统计信息 (AJAX)
     */
    @GetMapping("/api/statistics")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getDishStatistics() {
        DishService.DishStatistics stats = dishService.getDishStatistics();
        
        Map<String, Object> response = new HashMap<>();
        response.put("totalCount", stats.getTotalCount());
        response.put("categoryStats", stats.getCategoryStats());
        response.put("nutritionStats", stats.getNutritionStats());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 高级搜索菜品 (AJAX)
     */
    @GetMapping("/api/search")
    @ResponseBody
    public ResponseEntity<Page<DishDto>> searchDishes(
            @RequestParam(required = false) Long categoryId,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String spiceLevel,
            @RequestParam(required = false) String cookingMethod,
            @RequestParam(required = false) BigDecimal minCalories,
            @RequestParam(required = false) BigDecimal maxCalories,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        Dish.SpiceLevel spiceLevelEnum = null;
        if (spiceLevel != null && !spiceLevel.isEmpty()) {
            spiceLevelEnum = Dish.SpiceLevel.valueOf(spiceLevel);
        }
        
        Dish.CookingMethod cookingMethodEnum = null;
        if (cookingMethod != null && !cookingMethod.isEmpty()) {
            cookingMethodEnum = Dish.CookingMethod.valueOf(cookingMethod);
        }
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("popularityScore").descending());
        Page<Dish> dishPage = dishService.searchDishes(categoryId, keyword, spiceLevelEnum, 
                                                      cookingMethodEnum, minCalories, maxCalories, pageable);
        
        Page<DishDto> dishDtoPage = dishPage.map(DishDto::fromDish);
        return ResponseEntity.ok(dishDtoPage);
    }

    /**
     * 获取热门菜品 (AJAX)
     */
    @GetMapping("/api/popular")
    @ResponseBody
    public ResponseEntity<List<DishDto>> getPopularDishes(@RequestParam(defaultValue = "10") int limit) {
        List<Dish> dishes = dishService.getPopularDishes(limit);
        List<DishDto> dishDtos = dishes.stream()
            .map(DishDto::fromDish)
            .collect(Collectors.toList());
        
        return ResponseEntity.ok(dishDtos);
    }
}
